package com.unionftech.common.permissions

import android.annotation.SuppressLint
import android.app.Activity
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentActivity
import com.tbruyelle.rxpermissions3.Permission
import com.tbruyelle.rxpermissions3.RxPermissions
import com.unionftech.common.R
import com.unionftech.common.common.language.DynamicResourceManager
import com.unionftech.common.permissions.tip.IAction
import com.unionftech.common.permissions.tip.ITipShowController
import com.unionftech.common.utils.Utils

class PermissionUtils private constructor(private val showController: ITipShowController) {
    private val noAskPermissions: MutableList<String> = ArrayList()
    private var requestCount = 0
    private var refuseCount = 0

    companion object {
        private const val TAG = "PermissionUtils"
        private var instance: PermissionUtils? = null
        private var callInitMethod = false

        @JvmStatic
        fun getInstance(): PermissionUtils {
            if (!callInitMethod) {
                throw RuntimeException("Please call init() method first")
            }
            return instance!!
        }

        /**
         * 初始化入口
         *
         * @param showController
         */
        @JvmStatic
        @Synchronized
        fun init(showController: ITipShowController) {
            if (instance != null) {
                return
            }
            callInitMethod = true
            instance = PermissionUtils(showController)
        }
    }

    fun request(
        activity: FragmentActivity, permissions: Array<String>, listener: PermissionListener
    ) {
        request(activity, permissions, false, listener)
    }

    fun request(
        activity: FragmentActivity,
        permissions: Array<String>,
        isShowTipDialog: Boolean,
        listener: PermissionListener
    ) {
        needShowTipsDialog(activity, isShowTipDialog, permissions) {
            requestPermissions(
                activity, permissions, listener
            )
        }
    }

    private fun needShowTipsDialog(
        activity: FragmentActivity,
        isShowTipDialog: Boolean = true,
        permissions: Array<String>,
        action: IAction
    ) {
        if (isShowTipDialog) {
            val needPermissions = getNeedPermissions(activity, permissions)
            if (needPermissions.isNotEmpty()) {
                showController.showTipDialog(activity, needPermissions, action)
            } else {
                action.onComplete()
            }
        } else {
            action.onComplete()
        }
    }

    @SuppressLint("CheckResult")
    private fun requestPermissions(
        activity: FragmentActivity, permissions: Array<String>, listener: PermissionListener
    ) {
        clearData()
        val size = permissions.size
        val rxPermissions = RxPermissions(activity)
        rxPermissions.requestEach(*permissions).subscribe { permission: Permission ->
            if (permission.granted) {
                //用户同意
                requestCount++
            } else if (permission.shouldShowRequestPermissionRationale) {
                //用户拒绝了权限，但没有勾选不可询问
                requestCount++
                refuseCount++
            } else {
                //用户拒绝了权限，并且勾选不可询问
                requestCount++
                refuseCount++
                noAskPermissions.add(permission.name)
            }
            handlePermissionResult(activity, size, listener)
        }
    }

    private fun handlePermissionResult(
        activity: FragmentActivity, size: Int, listener: PermissionListener?
    ) {
        if (size == requestCount) {
            if (refuseCount == 0 && noAskPermissions.size == 0) {
                //全部允许
                listener?.accept()
            } else if (noAskPermissions.size == 0) {
                //拒绝权限
                listener?.refuse()
            } else {
                if (listener != null) {
                    val userHandle = listener.noAsk()
                    if (!userHandle) {
                        //引导用户去设置界面
                        showGotoSettingDialog(activity)
                    }
                } else {
                    showGotoSettingDialog(activity)
                }
            }
        }
    }

    private fun showGotoSettingDialog(activity: FragmentActivity) {
        val appName = Utils.getAppName(activity)
        val title = DynamicResourceManager.getString(R.string.string_permission_request)
        val stringMessage =
            DynamicResourceManager.getString(R.string.string_permission_goto_setting_msg)
        val resultMessage =
            stringMessage.replace("<ph1></ph1>", appName)
        showController.showGotoSettingDialog(activity, title, resultMessage) {
            //跳转到设置界面
            JumpPermissionUtils.gotoSetting(activity)
        }
    }

    private fun clearData() {
        noAskPermissions.clear()
        requestCount = 0
        refuseCount = 0
    }

    private fun getNeedPermissions(activity: Activity, permissions: Array<String>): Array<String> {
        val permissionList: MutableList<String> = ArrayList()
        for (permission in permissions) {
            if (checkNeedPermission(activity, permission)) {
                permissionList.add(permission)
            }
        }
        return permissionList.toTypedArray()
    }

    private fun checkNeedPermission(activity: Activity, permission: String): Boolean {
        val state = ActivityCompat.checkSelfPermission(activity, permission)
        return state != PackageManager.PERMISSION_GRANTED
    }


}